
package com.hexinfo.dmpro.script.publish.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hexinfo.dmpro.common.base.PageResult;
import com.hexinfo.dmpro.common.model.ClusterSparingConf;
import com.hexinfo.dmpro.common.service.ClusterSparingConfService;
import com.hexinfo.dmpro.common.utils.CommonConstants;
import com.hexinfo.dmpro.script.config.model.ConfigPropertyPublishuser;
import com.hexinfo.dmpro.script.config.model.RolesPublishuser;
import com.hexinfo.dmpro.script.config.service.ConfigPropertyPublishuserService;
import com.hexinfo.dmpro.script.config.service.RolesPublishuserService;
import com.hexinfo.dmpro.script.pack.entity.ScriptPackTaskEntity;
import com.hexinfo.dmpro.script.pack.service.IScriptPackTaskService;
import com.hexinfo.dmpro.script.publish.dao.ScriptPublishVersionMapper;
import com.hexinfo.dmpro.script.publish.entity.ScriptPublishTaskEntity;
import com.hexinfo.dmpro.script.publish.entity.ScriptPublishVersionEntity;
import com.hexinfo.dmpro.script.publish.service.IScriptPublishTaskService;
import com.hexinfo.dmpro.script.publish.service.IScriptPublishVersionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 脚本发布任务
 *
 * @author Wang zhihao
 * @date 2023-09-13 18:16:07
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class ScriptPublishVersionServiceImpl extends ServiceImpl<ScriptPublishVersionMapper, ScriptPublishVersionEntity> implements IScriptPublishVersionService {

//    @Value("${script.publish.configFilePath}")
//    private String configFilePath;

    private final IScriptPublishTaskService scriptPublishTaskService;

    private final ClusterSparingConfService clusterSparingConfService;

    private final RolesPublishuserService rolesPublishuserService;

    private final ConfigPropertyPublishuserService configPropertyPublishuserService;

    private final IScriptPackTaskService scriptPackTaskService;

    /**
     * @Method queryList
     * @Param
     * @param page
     * @param scriptPublishVersion
     * @Return com.hexinfo.dmpro.common.base.PageResult
     * @Description 分页查询
     * @Author Wang zhihao
     * @Date 2023/11/30 14:13
     * @Version V1.0
     */
    @Override
    public PageResult queryList(Page page, ScriptPublishVersionEntity scriptPublishVersion) {
        LambdaQueryWrapper<ScriptPublishVersionEntity> wrapper = beforeQuery(scriptPublishVersion);
        Page returnPage = baseMapper.selectPage(page, wrapper);
        List<ScriptPublishVersionEntity> scriptPublishVersions = returnPage.getRecords();
        afterQuery(returnPage.getRecords());
        return new PageResult(scriptPublishVersions, returnPage.getTotal());
    }

    /**
     * @Method beforeQuery
     * @Param
     * @param scriptPublishVersion
     * @Return com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<com.hexinfo.dmpro.script.publish.entity.ScriptPublishVersionEntity>
     * @Description 查询前置条件
     * @Author Wang zhihao
     * @Date 2023/11/30 20:16
     * @Version V1.0
     */
    private LambdaQueryWrapper<ScriptPublishVersionEntity> beforeQuery(ScriptPublishVersionEntity scriptPublishVersion) {
        LambdaQueryWrapper<ScriptPublishVersionEntity> wrapper = Wrappers.lambdaQuery();
        if (StrUtil.isNotBlank(scriptPublishVersion.getId())) {
            wrapper.eq(ScriptPublishVersionEntity::getId, scriptPublishVersion.getId());
        }
        if (StrUtil.isNotBlank(scriptPublishVersion.getScriptPublishName())) {
            wrapper.like(ScriptPublishVersionEntity::getScriptPublishName, scriptPublishVersion.getScriptPublishName());
        }
        if (StrUtil.isNotBlank(scriptPublishVersion.getOnlineDate())) {
            wrapper.like(ScriptPublishVersionEntity::getOnlineDate, scriptPublishVersion.getOnlineDate());
        }
        if (StrUtil.isNotBlank(scriptPublishVersion.getDemandCode())) {
            wrapper.like(ScriptPublishVersionEntity::getDemandCode, scriptPublishVersion.getDemandCode());
        }
        wrapper.orderByDesc(ScriptPublishVersionEntity::getCreateTime);
        return wrapper;
    }

    private void afterQuery(List<ScriptPublishVersionEntity> scriptPublishVersions) {
        List<ClusterSparingConf> clusterSparingConfList = clusterSparingConfService.queryListNoPage(new ClusterSparingConf());
        Map<String, ClusterSparingConf> clusterSparingConfMap = clusterSparingConfList.stream().collect(Collectors.toMap(ClusterSparingConf::getId, clusterSparingConf -> clusterSparingConf));
        scriptPublishVersions.forEach(scriptPublishVersion -> {
            ScriptPackTaskEntity scriptPackTask  = scriptPackTaskService.getById(scriptPublishVersion.getPackTaskId());
            scriptPublishVersion.setScriptPackName(scriptPackTask.getScriptPackName());
            scriptPublishVersion.setAppointClusterName(clusterSparingConfMap.containsKey(scriptPublishVersion.getAppointClusterId()) ? clusterSparingConfMap.get(scriptPublishVersion.getAppointClusterId()).getClusterName() : "");
            scriptPublishVersion.setAppointClusterWeight(clusterSparingConfMap.containsKey(scriptPublishVersion.getAppointClusterId()) ? clusterSparingConfMap.get(scriptPublishVersion.getAppointClusterId()).getClusterWeight() : 0);
        });
    }

    /**
     * @Method removeByIds
     * @Param
     * @param ids
     * @Return void
     * @Description 根据主键批量删除
     * @Author Wang zhihao
     * @Date 2023/11/30 20:19
     * @Version V1.0
     */
    @Override
    public void removeByIds(List<String> ids) {
        ids.forEach(this::removeById);
    }

    /**
     * @Method removeById
     * @Param
     * @param id
     * @Return void
     * @Description 根据主键删除
     * @Author Wang zhihao
     * @Date 2023/11/30 20:19
     * @Version V1.0
     */
    @Override
    public void removeById(String id) {
        baseMapper.deleteById(id);
        scriptPublishTaskService.removeByVersionId(id);

    }

    /**
     * @Method publish
     * @Param
     * @param scriptPublishVersion
     * @param clusterIds
     * @param publishUser
     * @Return void
     * @Description 指定集群发布
     * @Author Wang zhihao
     * @Date 2023/11/29 19:08
     * @Version V1.0
     */
    @Override
    public void publish(ScriptPublishVersionEntity scriptPublishVersion, String serverIds, String clusterIds, String publishUser) {
        ScriptPackTaskEntity scriptPackTask = scriptPackTaskService.getById(scriptPublishVersion.getPackTaskId());
        if (Objects.equals(scriptPackTask.getDel(), CommonConstants.STATUS_DEL)) {
            throw new RuntimeException("对应的打包任务已删除，无法执行发布操作");
        }
        scriptPublishTaskService.addPublishTask(new ScriptPublishTaskEntity()
                .setPublishClusterIds(clusterIds)
                .setPublishVersionId(scriptPublishVersion.getId())
                .setPackTaskId(scriptPublishVersion.getPackTaskId())
                .setMasterPackagePath(scriptPublishVersion.getMasterPackagePath())
                .setServerIds(serverIds)
                .setPublishUser(publishUser)
        );
    }

    /**
     * @Method getUserListByCluster
     * @Param
     * @param clusterName
     * @Return java.util.List<java.lang.String>
     * @Description 获取脚本发布可选用户列表
     * @Author Wang zhihao
     * @Date 2024/1/10 15:01
     * @Version V1.0
     */
    @Override
    public List<String> getUserListByCluster(String clusterName) {
        try {
            Set<String> userList = new HashSet<>();
            List<ConfigPropertyPublishuser> publishUserList = configPropertyPublishuserService.findAll();
            for (ConfigPropertyPublishuser c :
                    publishUserList) {
                userList.add(c.getUsername());
            }
            return new ArrayList<>(userList);
        } catch (Exception e) {
            throw new RuntimeException(StrUtil.format("【{}】配置文件获取发布用户异常", clusterName));
        }
    }
    //通过发布服务器id和登录用户获取脚本发布用户列表
    @Override
    public List<String> getUserListByClusterAndId(String serverId,List<String> ids) {
        //发布服务器获取
        ConfigPropertyPublishuser configPropertyPublishuser = new ConfigPropertyPublishuser();
        configPropertyPublishuser.setServerId(serverId);
        List<ConfigPropertyPublishuser> cList = configPropertyPublishuserService.findList(configPropertyPublishuser);
        //登录用户获取
        Set<RolesPublishuser> rSet = new HashSet<>();
        for (String id : ids) {
            List<RolesPublishuser> rList = rolesPublishuserService.queryListNoPage(id);
            for (int i = 0; i < rList.size(); i++) {
                rSet.add(rList.get(i));
            }
        }
        List<String> result = new ArrayList<>();
        for (ConfigPropertyPublishuser c : cList) {
            for (RolesPublishuser r : rSet) {
                if (!("true".equals(c.getDisabled()))&&c.getUsername().equals(r.getPublishuserUsername())) {
                    result.add(c.getUsername());
                }
            }
        }
        return result;
    }
}
